home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK2.toast / Development Kits / Hardware / PCI Driver Development Kit / • Tools / Utility / LoadDriverTest 950518 / Src / LoadDriverTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  13.0 KB  |  616 lines  |  [TEXT/MPCC]

  1. /*                                    LoadDriverTest.c                                */
  2. /*
  3.  * LoadDriverTest.c
  4.  * Copyright © 1994 Apple Computer Inc. All Rights Reserved.
  5.  */
  6. /*    .___________________________________________________________________________________.
  7.       | This utility checks that a PCI 'ndrv' driver can be loaded - it opens the driver    |
  8.       | file as a shared library and checks that the required exported symbols are found.    |                                                                |
  9.     .___________________________________________________________________________________.
  10.  */
  11.  
  12. #define EXTERN /* Nothing */
  13. #include "LoadDriverTest.h"
  14.  
  15. #if MPW
  16. QDGlobals                qd;
  17. #endif
  18.  
  19. void                        ProcessThisEvent(
  20.         const EventRecord        *eventRecordPtr,
  21.         long                    *sleepTimePtr
  22.     );
  23. void                        DoMouseEvent(
  24.         const EventRecord        *eventRecordPtr
  25.     );
  26. void                        DoCommand(
  27.         long                    menuChoice
  28.     );
  29. void                        DoFileOpen(void);
  30. OSErr                        TestDriverFragment(
  31.         const FSSpecPtr            theFSSpecPtr
  32.     );
  33. void                        TestCodeFragment(
  34.         const FSSpecPtr            theFSSpecPtr
  35.     );
  36. Boolean                        CheckSymbol(
  37.         CFragConnectionID            connID,
  38.         ConstStr255Param            fileName,
  39.         ConstStr255Param            symbolName
  40.     );
  41. void                        DoAbout(void);
  42. void                        AdjustMenus(void);
  43. void                        EnableEditMenu(void);
  44. pascal OSErr                MyAEOpenAppHandlerFunc(
  45.         long                    refCon
  46.     );
  47. pascal OSErr                MyAEOpenDocHandlerFunc(
  48.         const FSSpecPtr            fsSpecPtr,
  49.         long                    refCon                /* Event refCon                */
  50.     );
  51. pascal OSErr                MyAEQuitAppHandlerFunc(
  52.         long                    refCon
  53.     );
  54. pascal void                    MyAEUnknownHandlerMsgFunc(
  55.         ConstStr255Param        messageText
  56.     );
  57. pascal Boolean                MyAEIdleProc(
  58.         const EventRecord        *theEventPtr,
  59.         long                    *sleepTime,
  60.         RgnHandle                *mouseRgn
  61.     );
  62. RoutineDescriptor        gAEIdleUPP =
  63.             BUILD_ROUTINE_DESCRIPTOR(uppAEIdleProcInfo, MyAEIdleProc);
  64. OSErr                        InitializeApplication(void);
  65.  
  66. void
  67. main(void)
  68. {
  69.         OSErr                status;
  70.         
  71.         status = InitializeApplication();
  72.         if (status == noErr) {
  73.             InitCursor();
  74.             while (gQuitNow == FALSE) {
  75.                 if (gUpdateMenusNeeded)
  76.                     AdjustMenus();
  77.                 WaitNextEvent(everyEvent, &gEventRecord, gSleepTime, NULL);
  78.                 gAECoreGlobals.currentEventIsAppleEvent = FALSE;
  79.                 ProcessThisEvent(&gEventRecord, &gSleepTime);
  80.             }
  81.         }
  82.         ExitToShell();
  83. }
  84.  
  85. pascal OSErr
  86. MyAEOpenAppHandlerFunc(
  87.         long                    refCon
  88.     )
  89. {        
  90.         UNUSED(refCon);
  91.         gOpenAppCalled = TRUE;
  92.         return (noErr);
  93. }
  94.  
  95. pascal OSErr
  96. MyAEOpenDocHandlerFunc(
  97.         const FSSpecPtr            fsSpecPtr,
  98.         long                    refCon                /* Event refCon                */
  99.     )
  100. {
  101.         UNUSED(refCon);
  102.         TestDriverFragment(fsSpecPtr);
  103.         /*
  104.          * If we are launched by dropping one or more ndrv files on the icon,
  105.          * quit after processing the last file.
  106.          */
  107.         if (gOpenAppCalled == FALSE)
  108.             gQuitNow = TRUE;
  109.         return (noErr);
  110. }
  111.         
  112. pascal OSErr
  113. MyAEQuitAppHandlerFunc(
  114.         long                    refCon
  115.     )
  116. {
  117.         UNUSED(refCon);
  118.         Message("\pMyAEQuitAppHandlerFunc");
  119.         gQuitNow = TRUE;
  120.         return (noErr);
  121. }
  122.  
  123.  
  124. pascal void
  125. MyAEUnknownHandlerMsgFunc(
  126.         ConstStr255Param        messageText
  127.     )
  128. {
  129.         NonFatalError(errAEHandlerNotFound, messageText);
  130. }
  131.  
  132.  
  133. void
  134. ProcessThisEvent(
  135.         const EventRecord        *eventRecordPtr,
  136.         long                    *sleepTimePtr
  137.     )
  138. {
  139.         long                    menuChoice;
  140.         register WindowPtr        theWindow;
  141.         GrafPtr                    savePort;
  142.         Boolean                    isActivating;
  143.         OSErr                    status;
  144.         
  145.         theWindow = FrontWindow();
  146.         switch (eventRecordPtr->what) {
  147.         case nullEvent:
  148.             break;
  149.         case keyDown:
  150.         case autoKey:
  151.             if ((eventRecordPtr->message & charCodeMask) == '.'
  152.              && (eventRecordPtr->modifiers & cmdKey) != 0) {
  153.                 FlushEvents(keyDown | autoKey, 0);
  154.                 gQuitNow = TRUE;
  155.             }
  156.             else if ((eventRecordPtr->modifiers & cmdKey) != 0) {
  157.                 if (eventRecordPtr->what == keyDown) {
  158.                     menuChoice = MenuKey(eventRecordPtr->message & charCodeMask);
  159.                     if (HiWord(menuChoice) != 0)
  160.                         DoCommand(menuChoice);
  161.                 }
  162.             }
  163.             break;
  164.         case mouseDown:
  165.             DoMouseEvent(eventRecordPtr);
  166.             break;
  167.         case updateEvt:
  168.             theWindow = (WindowPtr) eventRecordPtr->message;
  169.             GetPort(&savePort);
  170.             SetPort(theWindow);
  171.             BeginUpdate(theWindow);
  172.             EraseRect(&theWindow->portRect);
  173.             DrawControls(theWindow);
  174.             DrawGrowIcon(theWindow);
  175.             EndUpdate(theWindow);
  176.             SetPort(savePort);
  177.             break;
  178.         case activateEvt:
  179.             theWindow = (WindowPtr) eventRecordPtr->message;
  180.             isActivating = ((eventRecordPtr->modifiers & activeFlag) != 0);
  181.             goto activateEvent;
  182.             break;
  183.         case kHighLevelEvent:
  184.             status = AEProcessAppleEvent(eventRecordPtr);
  185.             if (status != noErr)
  186.                 NonFatalError(status, "\pAppleEvent error");
  187.             break;
  188.         case osEvt:
  189.             switch (((unsigned long) eventRecordPtr->message) >> 24) {
  190.             case mouseMovedMessage:
  191.                 break;
  192.             case suspendResumeMessage:
  193.                 isActivating = ((eventRecordPtr->message & 0x01) != 0);
  194. activateEvent:        if (isActivating) {
  195.                     /*
  196.                      * Activate this window. Activate events define theWindow
  197.                      * from the event record, while suspend/resume uses the
  198.                      * pre-set FrontWindow value.
  199.                      */
  200.                     SelectWindow(theWindow);
  201.                     (void) TEFromScrap();
  202.                 }
  203.                 gInForeground = isActivating;
  204.                 *sleepTimePtr = (gInForeground) ? 6 : 60;
  205.                 gUpdateMenusNeeded = TRUE;
  206.                 break;
  207.             }
  208.             break;
  209.         }
  210. }
  211.  
  212. /*
  213.  * DoMouseEvent
  214.  * The user clicked on something. Handle application-wide processing here, or call
  215.  * a Catalog Browser function for specific action.
  216.  */
  217. void
  218. DoMouseEvent(
  219.         const EventRecord        *eventRecordPtr
  220.     )
  221. {
  222.         WindowPtr        theWindow;
  223.         short            whichPart;
  224.         
  225.         whichPart = FindWindow(eventRecordPtr->where, &theWindow);
  226.         switch (whichPart) {
  227.         case inMenuBar:
  228.             InitCursor();
  229.             DoCommand(MenuSelect(eventRecordPtr->where));
  230.             break;
  231.         }
  232. }
  233.  
  234. void
  235. DoCommand(
  236.         long                    menuChoice
  237.     )
  238. {
  239.         short                    menuItem;
  240.         Str255                    menuText;
  241.         GrafPtr                    savePort;
  242.  
  243.         menuItem = LoWord(menuChoice);
  244.         switch (HiWord(menuChoice)) {
  245.         case MENU_Apple:
  246.             if (menuItem == kAppleAbout)
  247.                 DoAbout();
  248.             else {
  249.                 EnableEditMenu();
  250.                 GetMenuItemText(gAppleMenu, menuItem, menuText);
  251.                 GetPort(&savePort);
  252.                 OpenDeskAcc(menuText);
  253.                 SetPort(savePort);
  254.                 gUpdateMenusNeeded = TRUE;
  255.             }
  256.             break;
  257.         case MENU_File:
  258.             switch (menuItem) {
  259.             case kFileOpen:
  260.                 DoFileOpen();
  261.                 break;
  262.             case kFileQuit:
  263.                 gQuitNow = TRUE;
  264.                 break;
  265.             }
  266.             break;
  267.         }
  268.         HiliteMenu(0);
  269. }
  270.  
  271. /*
  272.  * AdjustMenus
  273.  * Enable/disable menu options.
  274.  */
  275. void
  276. AdjustMenus(void)
  277. {
  278.         EnableItem(gAppleMenu, kAppleAbout);
  279.         EnableItem(gFileMenu, kFileQuit);
  280.         EnableItem(gFileMenu, kFileOpen);
  281.         DisableItem(gEditMenu, kEditUndo);
  282.         DisableItem(gEditMenu, kEditCut);
  283.         DisableItem(gEditMenu, kEditCopy);
  284.         DisableItem(gEditMenu, kEditPaste);
  285.         DisableItem(gEditMenu, kEditClear);
  286.         gUpdateMenusNeeded = FALSE;
  287. }
  288.  
  289. /*
  290.  * EnableEditMenu
  291.  * Enable Edit Menu options.
  292.  */
  293. void
  294. EnableEditMenu(void)
  295. {
  296.         EnableItem(gEditMenu, kEditUndo);
  297.         EnableItem(gEditMenu, kEditCut);
  298.         EnableItem(gEditMenu, kEditCopy);
  299.         EnableItem(gEditMenu, kEditPaste);
  300.         EnableItem(gEditMenu, kEditClear);
  301. }
  302.  
  303.  
  304. void
  305. DoFileOpen(void)
  306. {
  307.         Point                where;
  308.         SFTypeList            typeList;
  309.         SFReply                sfReply;
  310.         FSSpec                theFSSpec;
  311.         OSErr                status;
  312.         
  313.         SetPt(&where, 0, 0);
  314.         typeList[0] = 'ndrv';
  315.         SFGetFile(
  316.             where,
  317.             NULL,
  318.             NULL,
  319.             1,
  320.             typeList,
  321.             NULL,
  322.             &sfReply
  323.         );
  324.         if (sfReply.good == FALSE)
  325.             status = abortErr;
  326.         else {
  327.             status = FSMakeFSSpec(
  328.                         sfReply.vRefNum,
  329.                         0,
  330.                         sfReply.fName,
  331.                         &theFSSpec
  332.                     );
  333.             CheckStatus(status, "\pFSMakeFSSpec failed");
  334.         }
  335.         if (status == noErr) {
  336.             status = TestDriverFragment(&theFSSpec);
  337.             if (status != noErr)
  338.                 TestCodeFragment(&theFSSpec);
  339.         }
  340. }
  341.  
  342.  
  343. /*
  344.  * Test whether we can load a driver.
  345.  */
  346. OSErr
  347. TestDriverFragment(
  348.         const FSSpecPtr            theFSSpecPtr
  349.     )
  350. {
  351.         OSErr                    status;
  352.         CFragConnectionID        connID;
  353.         DriverEntryPointPtr        fragmentMain;
  354.         DriverDescriptionPtr    theDriverDesc;
  355.         Str15                    errValue;
  356.  
  357.         status = GetDriverDiskFragment(
  358.                     theFSSpecPtr,
  359.                     &connID,
  360.                     &fragmentMain,
  361.                     &theDriverDesc
  362.                 );
  363.         if (status == noErr) {
  364.             (void) CloseConnection(&connID);
  365.             ParamText(
  366.                 theFSSpecPtr->name,
  367.                 theDriverDesc->driverType.nameInfoStr,
  368.                 theDriverDesc->driverOSRuntimeInfo.driverName,
  369.                 "\p"
  370.             );
  371.             NoteAlert(ALRT_DriverOK, NULL);
  372.         }
  373.         else {
  374.             NumToString(status, errValue);
  375.             ParamText(
  376.                 errValue,
  377.                 theFSSpecPtr->name,
  378.                 "\p(Unknown)",
  379.                 "\p"
  380.             );
  381.             InitCursor();
  382.             StopAlert(ALRT_FragLoadErr, NULL);
  383.         }
  384.         return (status);
  385. }
  386.  
  387. /*
  388.  * Test whether we can load a Code Fragment -- the driver test failed;
  389.  * this test might say why. Note: it is only correct for 'ndrv' drivers.
  390.  */
  391. void
  392. TestCodeFragment(
  393.         const FSSpecPtr            theFSSpecPtr
  394.     )
  395. {
  396.         OSErr                    status;
  397.         CFragConnectionID        connID;
  398.         Ptr                        mainAddress;
  399.         Str255                    errName;
  400.         Str15                    errValue;
  401.  
  402.         status = GetDiskFragment(
  403.                     theFSSpecPtr,
  404.                     0,                        /* Offset                */
  405.                     0, // kWholeFork,        /* Fragment size        */
  406.                     theFSSpecPtr->name,        /* Fragment name        */
  407.                     kLoadCFrag,                /* Load the fragment    */
  408.                     &connID,                /* Connection ID        */
  409.                     &mainAddress,            /* -> main address        */
  410.                     errName
  411.                 );
  412.         if (status != noErr) {
  413.             NumToString(status, errValue);
  414.             ParamText(
  415.                 errValue,
  416.                 theFSSpecPtr->name,
  417.                 errName,
  418.                 "\p"
  419.             );
  420.             InitCursor();
  421.             StopAlert(ALRT_FragLoadErr, NULL);
  422.         }
  423.         else {
  424.             /*
  425.              * The fragment is present, make sure the exported symbols
  426.              * are also present. Note the single & -- this ensures that
  427.              * CheckSymbol is called for both exported symbols.
  428.              */
  429.             if (CheckSymbol(connID, theFSSpecPtr->name, "\pTheDriverDescription")
  430.               & CheckSymbol(connID, theFSSpecPtr->name, "\pDoDriverIO")) {
  431.                   ParamText(theFSSpecPtr->name, "\p(?)", "\p(?)", "\p");
  432.                 NoteAlert(ALRT_DriverOK, NULL);
  433.             }
  434.             (void) CloseConnection(&connID);
  435.         }
  436. }
  437.  
  438. Boolean
  439. CheckSymbol(
  440.         CFragConnectionID            connID,
  441.         ConstStr255Param            fileName,
  442.         ConstStr255Param            symbolName
  443.     )
  444. {
  445.         OSErr                    status;
  446.         Str15                    errValue;
  447.         Ptr                        symAddr;
  448.         CFragSymbolClass        symClass;
  449.  
  450.         status = FindSymbol(
  451.                     connID,
  452.                     symbolName,
  453.                     &symAddr,
  454.                     &symClass
  455.                 );
  456.         if (status != noErr) {
  457.             NumToString(status, errValue);
  458.             ParamText(
  459.                 errValue,
  460.                 fileName,
  461.                 symbolName,
  462.                 "\p"
  463.             );
  464.             InitCursor();
  465.             StopAlert(ALRT_SymbolErr, NULL);
  466.         }
  467.         return (status == noErr);
  468. }
  469.  
  470. void
  471. DoAbout(void)
  472. {
  473.         GrafPtr                    savePort;
  474.         DialogPtr                dialog;
  475.         short                    dialogItem;
  476.  
  477.         dialog = GetNewDialog(DLOG_About, NULL, (WindowPtr) -1L);
  478.         if (dialog != NULL) {
  479.             GetPort(&savePort);
  480.             SetPort(dialog);
  481.             ShowWindow(dialog);
  482.             ModalDialog(NULL, &dialogItem);
  483.             DisposeDialog(dialog);
  484.             SetPort(savePort);
  485.         }
  486. }
  487.  
  488. void
  489. NonFatalError(
  490.         OSErr                    errorStatus,
  491.         ConstStr255Param        errorMsg
  492.     )
  493. {
  494.         if (ErrorMessage(ALRT_NonFatalError, errorStatus, errorMsg) == kOKButton)
  495.             gQuitNow = TRUE;
  496. }
  497.  
  498. void
  499. FatalError(
  500.         OSErr                    errorStatus,
  501.         ConstStr255Param        errorMsg
  502.     )
  503. {
  504.         ErrorMessage(ALRT_FatalError, errorStatus, errorMsg);
  505.         ExitToShell();
  506. }
  507.  
  508. void
  509. Message(
  510.         ConstStr255Param        message
  511.     )
  512. {
  513.         ParamText(message, "\p", "\p", "\p");
  514.         NoteAlert(ALRT_Empty, NULL);
  515. }
  516.  
  517. short
  518. ErrorMessage(
  519.         short                    alertID,
  520.         OSErr                    errorStatus,
  521.         ConstStr255Param        errorMsg
  522.     )
  523. {
  524.         Handle                    errorTextHdl;
  525.         StringPtr                errorTextPtr;
  526.         Str15                    errorStatusText;
  527.         short                    result;
  528.         
  529.         if (AEInteractionOK((AEIdleUPP) &gAEIdleUPP) == FALSE)
  530.             result = kCancelButton;
  531.         else {
  532.             NumToString(errorStatus, errorStatusText);
  533.             errorTextHdl = GetResource('Estr', errorStatus);
  534.             if (errorTextHdl != NULL) {
  535.                 HLock(errorTextHdl);
  536.                 errorTextPtr = (StringPtr) errorTextHdl;
  537.             }
  538.             else {
  539.                 errorTextPtr = "\pSystem Error";
  540.             }
  541.             ParamText(errorStatusText, errorTextPtr, errorMsg, "\p");
  542.             InitCursor();
  543.             result = StopAlert(alertID, NULL);
  544.             if (errorTextHdl != NULL)
  545.                 ReleaseResource(errorTextHdl);
  546.         }
  547.         return (result);
  548. }
  549.  
  550. pascal Boolean
  551. MyAEIdleProc(
  552.         const EventRecord        *theEventPtr,
  553.         long                    *sleepTime,
  554.         RgnHandle                *mouseRgn
  555.     )
  556. {
  557.         UNUSED(mouseRgn);
  558.         if (theEventPtr->what == kHighLevelEvent)
  559.             return (TRUE);
  560.         else {
  561.             ProcessThisEvent(theEventPtr, sleepTime);    /* Application specific    */
  562.             return (FALSE);
  563.         }
  564. }        
  565.  
  566. OSErr
  567. InitializeApplication(void)
  568. {
  569.         OSErr                    status;
  570.         short                    i;
  571.         
  572.         status = noErr;
  573.         MaxApplZone();
  574.         InitGraf(&qd.thePort);
  575.         InitFonts();
  576.         InitWindows();
  577.         InitMenus();
  578.         TEInit();
  579.         InitDialogs(0);
  580.         for (i = 0; i < 8; i++)
  581.             MoreMasters();
  582.         for (i = 0; i < 3; i++)
  583.             EventAvail(everyEvent, &gEventRecord);
  584.         HNoPurge((Handle) GetCursor(watchCursor));
  585.         SetCursor(*GetCursor(watchCursor));
  586.         SetMenuBar(GetNewMBar(MBAR_MenuBar));
  587.         gAppleMenu = GetMenuHandle(MENU_Apple);
  588.         if (gAppleMenu == NULL) {
  589.             status = resNotFound;
  590.             FatalError(resNotFound, "\pNo Apple Menu");
  591.         }
  592.         if (status == noErr) {
  593.             AppendResMenu(gAppleMenu, 'DRVR');
  594.             gFileMenu = GetMenuHandle(MENU_File);
  595.             if (gFileMenu == NULL) {
  596.                 status = resNotFound;
  597.                 FatalError(resNotFound, "\pNo File Menu");
  598.             }
  599.         }
  600.         if (status == noErr) {
  601.             DrawMenuBar();
  602.             gUpdateMenusNeeded = TRUE;
  603.             status = InitializeAppleEvents(
  604.                         MyAEOpenAppHandlerFunc,            /* Open application            */
  605.                         MyAEOpenDocHandlerFunc,            /* Open document            */
  606.                         NULL,                            /* No Print Doc handler        */
  607.                         MyAEQuitAppHandlerFunc,            /* Quit application            */
  608.                         NULL,                            /* No Do Script Callback    */
  609.                         MyAEUnknownHandlerMsgFunc,        /* Strange AppleEvent        */
  610.                         0                                /* RefCon                    */
  611.                     );
  612.             if (status != noErr)
  613.                 FatalError(status, "\pCan't initialize AppleEvents");
  614.         }
  615.         return (status);
  616. }